package tasks.zhuanyeji.TLV问题;

import java.util.ArrayList;
import java.util.List;

public class TLV解析 {

    public static List<String> parseTLV(String hexStream) {
        List<String> result = new ArrayList<>();
        parseRecursive(hexStream, 0, 0, result);
        return result;
    }

    // 递归解析函数
    // hex: 整个十六进制字符串
    // start: 当前解析位置（字符索引，每个字节=2字符）
    // level: 当前嵌套层级
    // result: 结果列表
    // 返回值：解析完当前 TLV 后的下一个位置（字符索引）
    private static int parseRecursive(String hex, int start, int level, List<String> result) {
        int pos = start;

        while (pos < hex.length()) {
            // 1. 读取 T (2 字节 = 4 字符)
            if (pos + 4 > hex.length()) break;
            String tagStr = hex.substring(pos, pos + 4);
            pos += 4;

            // 2. 读取 L (4 字节 = 8 字符)
            if (pos + 8 > hex.length()) break;
            String lenStr = hex.substring(pos, pos + 8);
            pos += 8;

            // 把 L 转成十进制长度
            int len = Integer.parseInt(lenStr, 16);

            // 3. 读取 V (len 字节 = 2*len 字符)
            if (pos + 2 * len > hex.length()) break;
            String valueHex = hex.substring(pos, pos + 2 * len);
            pos += 2 * len;

            // 判断是否是嵌套 TLV：看 T 的第一个字节最高位是否为 1
            // tagStr 前两个字符是第一个字节
            int firstByte = Integer.parseInt(tagStr.substring(0, 2), 16);
            boolean isNested = (firstByte & 0x80) != 0;

            if (isNested) {
                // 是嵌套 TLV：递归解析 valueHex
                // 注意：valueHex 可能包含多个 TLV，所以用 while 循环解析完
                int subPos = 0;
                while (subPos < valueHex.length()) {
                    subPos = parseRecursive(valueHex, subPos, level + 1, result);
                }
            } else {
                // 非嵌套：把 valueHex 转成 ASCII 字符串
                String content = hexToAscii(valueHex);
                result.add(level + ":" + content);
            }

            // 如果当前是在顶层调用（level=0），并且只解析一个 TLV？
            // ❌ 不对！题目说输入是一个完整 TLV，但嵌套内部可能有多个并列 TLV
            // 所以必须用 while 循环继续解析后续（如顶级有多个 TLV 并列）
            // 但题目说明：“输入是一个合法的、完整的 TLV” → 通常指一个根 TLV
            // 然而，嵌套的 V 中可能有多个 TLV，所以递归中要 while
            // 但顶层是否可能有多个？题目样例只有一个。为安全起见，还是 while
        }

        return pos; // 返回下一个位置
    }

    // 辅助函数：十六进制字符串转 ASCII 字符串
    private static String hexToAscii(String hex) {
        if (hex.isEmpty()) return "";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < hex.length(); i += 2) {
            String byteStr = hex.substring(i, i + 2);
            int byteVal = Integer.parseInt(byteStr, 16);
            // 题目说 V 域内容为可见字符，所以直接转 char
            sb.append((char) byteVal);
        }
        return sb.toString();
    }

    // 测试
    public static void main(String[] args) {
        String input = "00000000000a68656c6c6f20776f7264";
        List<String> output = parseTLV(input);
        System.out.println(output); // [0:hello word]

        // 更复杂测试：嵌套
        // T=8001（嵌套），L=00000014（20字节），V=两个子TLV
        // 子1: T=0001, L=00000005, V="hello"
        // 子2: T=0002, L=00000005, V="world"
        // hex:
        // T:8001 → "8001"
        // L:00000014 → "00000014"
        // V:
        //   子1: "0001" + "00000005" + "68656c6c6f"
        //   子2: "0002" + "00000005" + "776f726c64"
        // 总V: "00010000000568656c6c6f000200000005776f726c64"
        String nested = "80010000001400010000000568656c6c6f000200000005776f726c64";
        System.out.println(parseTLV(nested));
        // 应输出: [1:hello, 1:world]
    }
}